#pragma onece
#include <iostream>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string>
#include <cstdio>
#include <cstring>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

const std::string pathname = "/home/yang/yang/lesson8/Shm/";
const size_t Shm_size = 4096; // 这个最好是4096的整数倍，因为shmget函数要求这么做
const int proj_it = 0x1234;   // 项目标识符
#define FIFO_FILE "./fifo"    // 创建管道的路径
#define MODE 0666             // 管道创建的权限
#define MAX_BUFFER_SIZE 1024  // 管道读写的最大缓存大小

enum // 出错码
{
    FIFO_CREATE_ERROR = 1,
    FIFO_OPEN_ERROR = 2,
    FIFO_WRITE_ERROR = 3,
    FIFO_READ_ERROR = 4,
    FIFO_CLOSE_ERROR = 5,
    FIFO_DELETE_ERROR = 6
};
class FIFO
{
public:
    FIFO()
    {
        int n = mkfifo(FIFO_FILE, MODE);
        if (n == -1)
        {
            perror("mkfifo error");
            exit(FIFO_CREATE_ERROR);
        }
    }
    ~FIFO()
    {
        int m = unlink(FIFO_FILE);
        if (m == -1)
        {
            perror("unlink error");
            exit(FIFO_DELETE_ERROR);
        }
    }
};
int Write_end(int fd)
{
    int n = write(fd, "c", sizeof(char)); // 发一个信号表示，我已写完，对方可以开始读了
    if (n < 0)
        return -1;
    return n;
}
int Read_begin(int fd)
{
    char c;
    int n = read(fd, &c, sizeof(char));  // 接受一个信号，表示对方已写完，我可以开始读了
    if (n < 0)
        return -1;
    return n;
}
key_t Getkey()
{
    int key = ftok(pathname.c_str(), proj_it);
    if (key < 0)
    {
        perror("ftok error");
        exit(1);
    }
    printf("key:0x%x\n", key);
    return key;
}

int GetShareMemory(int flag)
{
    key_t key = Getkey();
    int shmid = shmget(key, Shm_size, flag);
    if (shmid < 0)
    {
        perror("shmget error");
        exit(2);
    }
    return shmid;
}

int CreateShm()
{
    return GetShareMemory(IPC_CREAT | IPC_EXCL | 0666);
}
int GetShm()
{
    return GetShareMemory(IPC_CREAT | 0666);
}
